package cn.tworice.common.util.cryption;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;

/**
 * 非对称加密
 * @author 二饭 [2023/6/23]
 **/
public class RSAUtils {
    public static void main(String[] args) throws Exception {
        // 生成RSA密钥对
        KeyPair keyPair = generateKeyPair();

        // 获取公钥和私钥
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        // 将公钥和私钥转换为字符串
        String publicKeyString = publicKeyToString(publicKey);
        String privateKeyString = privateKeyToString(privateKey);
        System.out.println("公钥："+publicKeyString);
        System.out.println("私钥："+privateKeyString);
        // 要加密的原始数据
        String originalData = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6InJvb3QiLCJleHAiOjE2ODkxNjc2NjIxMzAsIm1hYyI6IjAwOjE1OjVEOjcwOjE1OjM1In0.WpSF2C07WD3RjpxKfld1OwVhkPyb0B65wsdkfwLz-eg";
        System.out.println("原Token: " + originalData);

        // 使用公钥字符串加密数据
        String encryptedDataString = encrypt(originalData, publicKeyString);
        System.out.println("加密后的Token: " + encryptedDataString);

        // 将加密后的数据字符串转换为字节数组
        byte[] encryptedData = stringToBytes(encryptedDataString);

        // 使用私钥字符串解密数据
        String decryptedData = decrypt(encryptedData, privateKeyString);
        System.out.println("解密后的数据: " + decryptedData);
    }

    /**
     * 生成RSA密钥对
     */
    public static KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);  // 设置密钥长度
        return keyPairGenerator.generateKeyPair();
    }

    /**
     * 将公钥转换为字符串
     */
    public static String publicKeyToString(PublicKey publicKey) {
        byte[] publicKeyBytes = publicKey.getEncoded();
        return Base64.getEncoder().encodeToString(publicKeyBytes);
    }

    /**
     * 将私钥转换为字符串
     */
    public static String privateKeyToString(PrivateKey privateKey) {
        byte[] privateKeyBytes = privateKey.getEncoded();
        return Base64.getEncoder().encodeToString(privateKeyBytes);
    }

    /**
     * 使用公钥字符串加密数据，并返回加密后的数据字符串
     */
    public static String encrypt(String data, String publicKeyString) throws Exception {
        PublicKey publicKey = stringToPublicKey(publicKeyString);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return bytesToString(encryptedBytes);
    }

    /**
     * 使用私钥字符串解密数据
     */
    public static String decrypt(byte[] encryptedData, String privateKeyString) throws Exception {
        PrivateKey privateKey = stringToPrivateKey(privateKeyString);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedData);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }

    /**
     * 将字节数组转换为字符串
     */
    public static String bytesToString(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }

    /**
     * 将字符串转换为字节数组
     */
    public static byte[] stringToBytes(String string) {
        return Base64.getDecoder().decode(string);
    }

    /**
     * 将字符串转换为公钥对象
     */
    public static PublicKey stringToPublicKey(String publicKeyString) throws Exception {
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString);
        return java.security.KeyFactory.getInstance("RSA").generatePublic(new java.security.spec.X509EncodedKeySpec(publicKeyBytes));
    }

    /**
     * 将字符串转换为私钥对象
     */
    public static PrivateKey stringToPrivateKey(String privateKeyString) throws Exception {
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyString);
        return java.security.KeyFactory.getInstance("RSA").generatePrivate(new java.security.spec.PKCS8EncodedKeySpec(privateKeyBytes));
    }
}
